//package com.scnu.hachimi.show;
//
//import com.scnu.hachimi.manager.MapLoader;
//import com.scnu.hachimi.manager.ResourcesManager;
//
//import javax.swing.*;
//import java.awt.*;
//import java.awt.event.KeyAdapter;
//import java.awt.event.KeyEvent;
//import java.awt.image.BufferedImage;
//import java.io.File;
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.OutputStream;
//import java.net.URISyntaxException;
//import java.net.URL;
//import java.net.URLDecoder;
//import java.nio.charset.StandardCharsets;
//import java.nio.file.*;
//import java.util.ArrayList;
//import java.util.Enumeration;
//import java.util.List;
//import java.util.Map;
//import java.util.jar.JarEntry;
//import java.util.jar.JarFile;
//
//public class OptionJPanel extends JPanel {
//    private ResourcesManager rm;
//
//    private int level = 0;
//    public int playerNum;
//    private int diff = 1;  //0/1/2
//    private ArrayList<String> mapName = new ArrayList<>();
//    private Map<String, List<Point>> mapData;
//    private Image offScreenImage = null;
//    private MainJFrame mjf;
//
//    public OptionJPanel(ResourcesManager rm, int playerNum, MainJFrame mjf) throws IOException {
//        this.setLayout(null);
//        this.setPreferredSize(new Dimension(800, 600));
//
//        this.rm = rm;
//        this.playerNum = playerNum;
//        this.mjf = mjf;
//
//        this.addKeyListener(new KeyboardListener());
//        this.setFocusable(true);
//
//        readMap("map");
//    }
//
//    public void readMap(String resourcePath) {
//        mapName.clear();
//        try {
//            // 获取资源URL（兼容IDE和JAR环境）
//            URL url = getClass().getClassLoader().getResource(resourcePath);
//            if (url == null) {
//                System.err.println("资源路径不存在: " + resourcePath);
//
//                //创建对应文件夹
//                Path targetDir = Paths.get("map");
//                if (!Files.exists(targetDir)) {
//                    Files.createDirectories(targetDir);
//                }
//
//                //将map文件夹中的文件复制到JAR包中
//                String sourcePath = "main/resources/map";
//                URL sourceUrl = getClass().getClassLoader().getResource(sourcePath);
//
//                if (sourceUrl != null) {
//                    // JAR环境
//                    if (sourceUrl.getProtocol().equals("jar")) {
//                        String jarPath = sourceUrl.getPath().substring(5, sourceUrl.getPath().indexOf("!"));
//                        jarPath = URLDecoder.decode(jarPath, StandardCharsets.UTF_8);
//
//                        try (JarFile jar = new JarFile(jarPath)) {
//                            Enumeration<JarEntry> entries = jar.entries();
//                            while (entries.hasMoreElements()) {
//                                JarEntry entry = entries.nextElement();
//                                String name = entry.getName();
//
//                                if (name.startsWith(sourcePath + "/") && name.endsWith(".map")) {
//                                    // 创建目标文件路径
//                                    String fileName = name.substring(name.lastIndexOf('/') + 1);
//                                    Path targetFile = targetDir.resolve(fileName);
//
//                                    // 复制文件
//                                    try (InputStream is = jar.getInputStream(entry);
//                                         OutputStream os = Files.newOutputStream(targetFile)) {
//                                        byte[] buffer = new byte[1024];
//                                        int bytesRead;
//                                        while ((bytesRead = is.read(buffer)) != -1) {
//                                            os.write(buffer, 0, bytesRead);
//                                        }
//                                    }
//                                }
//                            }
//                        }
//                    }
//                    // IDE环境
//                    else if (sourceUrl.getProtocol().equals("file")) {
//                        Path sourceDir = Paths.get(sourceUrl.toURI());
//                        try (DirectoryStream<Path> stream = Files.newDirectoryStream(sourceDir)) {
//                            for (Path sourceFile : stream) {
//                                if (sourceFile.toString().endsWith(".map")) {
//                                    Path targetFile = targetDir.resolve(sourceFile.getFileName());
//                                    Files.copy(sourceFile, targetFile, StandardCopyOption.REPLACE_EXISTING);
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//
//            // 文件系统路径（IDE环境）
//            if (url.getProtocol().equals("file")) {
//                File folder = new File(url.toURI());
//                if (folder.exists() && folder.isDirectory()) {
//                    File[] files = folder.listFiles();
//                    if (files != null) {
//                        for (File file : files) {
//                            if (file.getName().endsWith(".map")) {
//                                mapName.add(file.getName());
//                            }
//                        }
//                    }
//                }
//            }
//            // JAR文件路径（打包后环境）
//            else if (url.getProtocol().equals("jar")) {
//                String jarPath = url.getPath().substring(5, url.getPath().indexOf("!"));
//                jarPath = URLDecoder.decode(jarPath, "UTF-8");
//                try (JarFile jar = new JarFile(jarPath)) {
//                    Enumeration<JarEntry> entries = jar.entries();
//                    while (entries.hasMoreElements()) {
//                        String name = entries.nextElement().getName();
//                        if (name.startsWith(resourcePath + "/") && name.endsWith(".map")) {
//                            mapName.add(name.substring(name.lastIndexOf('/') + 1));
//                        }
//                    }
//                }
//            }
//        } catch (URISyntaxException | IOException e) {
//            e.printStackTrace();
//        }
//    }
//
////    public void readMap(String Path) throws IOException {
////        //如果没有map文件夹或者map文件夹中没有.map文件夹则创建map，然后把map软件包中的文件复制进去
////
////        Path mapDir = Paths.get("map");
////        Path dotMapDir = mapDir.resolve(".map");
////
////        // 检查条件：map文件夹不存在 或 map文件夹内没有.map子文件夹
////        if (!Files.exists(mapDir) || !Files.exists(dotMapDir)) {
////            // 创建map文件夹（如果不存在）
////            if (!Files.exists(mapDir)) {
////                Files.createDirectories(mapDir);
////            }
////
////            // 复制软件包内容到map文件夹
////            Path sourceDir = Paths.get(Path);
////            if (Files.exists(sourceDir)) {
////                try (DirectoryStream<Path> stream = Files.newDirectoryStream(sourceDir)) {
////                    for (Path sourceFile : stream) {
////                        Path targetFile = mapDir.resolve(sourceFile.getFileName());
////                        Files.copy(sourceFile, targetFile, StandardCopyOption.REPLACE_EXISTING);
////                    }
////                }
////            } else {
////                throw new IOException("源软件包路径不存在: " + Path);
////            }
////        }
////
////        //读取map文件夹中所以map的名称
////        mapName.clear();
////        File folder = new File(Path);
////        if (folder.exists() && folder.isDirectory()) {
////            File[] files = folder.listFiles(); // 获取目录下所有项
////            if (files != null) {
////                for (File file : files) {
////                    System.out.println(file.getName()); // 输出文件名
////                    //如果后缀是.map则加入
////                    if (file.getName().endsWith(".map")) {
////                        mapName.add(file.getName());
////                    }
////                }
////            }
////        } else {
////            System.err.println("路径无效或不是文件夹");
////        }
////    }
//
//    public void paint(Graphics g) {
//        //双缓冲
//        if (offScreenImage == null) {
//            offScreenImage = this.createImage(this.getWidth(), this.getHeight());
//        }
//        Graphics gOff = offScreenImage.getGraphics();
//
//        Image img = rm.imageMap.get("option");
//        gOff.drawImage(img, 0, 0, null);
//
//        gOff.setColor(Color.white);
//        gOff.setFont(new Font("微软雅黑", Font.BOLD, 24));
//        gOff.drawString(mapName.get(level), 50, 440);
//        //012对应普通，中等，困难
//        switch (diff) {
//            case 0:
//                gOff.drawString("普通", 65, 230);
//                break;
//            case 1:
//                gOff.drawString("中等", 65, 230);
//                break;
//            case 2:
//                gOff.drawString("困难", 65, 230);
//                break;
//        }
//        gOff.drawString("Esc返回", 45, 40);
//
//        BufferedImage mapImage = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
//        Graphics2D gMap = mapImage.createGraphics();
//        gMap.setComposite(AlphaComposite.Clear);
//        gMap.fillRect(0, 0, 800, 600);
//        gMap.setComposite(AlphaComposite.SrcOver);
//
//        gMap.setStroke(new BasicStroke(3)); // 设置边框粗细
//        gMap.setColor(Color.WHITE);
//        gMap.drawRect(0, 0, 800, 600);
//
//        try {
//            mapData = MapLoader.getMap("map/" + mapName.get(level));
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//
//
//
//        for (String terrainType : mapData.keySet()) {
//            List<Point> points = mapData.get(terrainType);
//            int w = 20, h = 20;
//            if (terrainType.equals("base") || terrainType.equals("elite") || terrainType.equals("BOSS") || terrainType.equals("player1") || terrainType.equals("player2")) w = h = 40;
//            for (Point point : points) {
//                gMap.drawImage(rm.imageMap.get(terrainType), point.x, point.y, w, h, null);
//            }
//        }
//
//
//
//        g.drawImage(offScreenImage, 0, 0, null);
//        g.drawImage(mapImage, 250, 100, 480, 360, null);
//    }
//
//
//    public class KeyboardListener extends KeyAdapter {
//        //监听wasd和回车键
//        public void keyPressed(KeyEvent e) {
//            switch (e.getKeyCode()) {
//                case KeyEvent.VK_W:
//                    level = (level + 1) % mapName.size();
//                    repaint();
//                    break;
//                case KeyEvent.VK_A:
//                    diff = (diff + 3 - 1) % 3;
//                    repaint();
//                    break;
//                case KeyEvent.VK_S:
//                    level = (level - 1 + mapName.size()) % mapName.size();
//                    repaint();
//                    break;
//                case KeyEvent.VK_D:
//                    diff = (diff + 1) % 3;
//                    repaint();
//                    break;
//                case KeyEvent.VK_ENTER:
//                    mjf.startGame(playerNum, diff, mapName.get(level));
//                    break;
//                case KeyEvent.VK_ESCAPE:
//                    mjf.showIndex();
//            }
//        }
//    }
//
////    public static void main(String[] args) {
////
////        // 创建窗口框架
////        JFrame frame = new JFrame("游戏设置");
////        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
////        frame.setResizable(false);
////
////        // 创建面板并添加到窗口
////        OptionJPanel optionJPanel = new OptionJPanel(new ResourcesManager("image"), 1, new MainJFrame());
////        frame.add(optionJPanel);
////
////        // 自动调整大小并显示
////        frame.pack();
////        frame.setLocationRelativeTo(null); // 居中显示
////        frame.setVisible(true); // 关键：设置窗口可见
////
////
////    }
//}
package com.scnu.hachimi.show;

import com.scnu.hachimi.manager.MapLoader;
import com.scnu.hachimi.manager.ResourcesManager;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class OptionJPanel extends JPanel {
    private final ResourcesManager rm;
    public int playerNum;
    private final MainJFrame mjf;

    private int level = 0;
    private int diff = 1;  // 0=普通, 1=中等, 2=困难
    private final ArrayList<String> mapNames = new ArrayList<>();
    private Map<String, List<Point>> mapData;
    private Image offScreenImage = null;

    public OptionJPanel(ResourcesManager rm, int playerNum, MainJFrame mjf) {
        this.setLayout(null);
        this.setPreferredSize(new Dimension(800, 600));
        this.rm = rm;
        this.playerNum = playerNum;
        this.mjf = mjf;
        this.addKeyListener(new KeyboardListener());
        this.setFocusable(true);

        // 确保地图文件夹存在并初始化
        ensureMapFolder();
    }

    /**
     * 确保地图文件夹存在并初始化地图文件
     */
    private void ensureMapFolder() {
        Path mapDir = Paths.get("map");

        try {
            // 1. 创建地图文件夹（如果不存在）
            if (!Files.exists(mapDir)) {
                Files.createDirectories(mapDir);
            }

            // 2. 检查地图文件夹中是否有.map文件
            boolean hasMapFiles = false;
            try (DirectoryStream<Path> stream = Files.newDirectoryStream(mapDir, "*.map")) {
                hasMapFiles = stream.iterator().hasNext();
            } catch (IOException e) {
                e.printStackTrace();
            }

            // 3. 如果没有地图文件，复制默认地图
            if (!hasMapFiles) {
                copyDefaultMaps(mapDir);
            }

            // 4. 加载地图名称
            loadMapNames(mapDir);
        } catch (IOException | URISyntaxException e) {
            throw new RuntimeException("无法初始化地图文件夹: " + e.getMessage(), e);
        }
    }

    /**
     * 从资源中复制默认地图到指定目录
     */
    private void copyDefaultMaps(Path targetDir) throws IOException, URISyntaxException {
        // 获取资源路径
        String resourcePath = "map";
        ClassLoader classLoader = getClass().getClassLoader();

        // 尝试获取资源URL
        java.net.URL resourceUrl = classLoader.getResource(resourcePath);

        if (resourceUrl == null) {
            throw new IOException("资源路径不存在: " + resourcePath);
        }

        // 根据协议类型处理不同的资源位置
        String protocol = resourceUrl.getProtocol();

        if ("jar".equals(protocol)) {
            // JAR 环境
            copyJarResources(resourceUrl, resourcePath, targetDir);
        } else if ("file".equals(protocol)) {
            // IDE 环境
            copyFileResources(Paths.get(resourceUrl.toURI()), targetDir);
        } else {
            throw new IOException("不支持的协议类型: " + protocol);
        }
    }

    /**
     * 从JAR文件中复制资源
     */
    private void copyJarResources(java.net.URL resourceUrl, String resourcePath, Path targetDir) throws IOException {
        String jarPath = resourceUrl.getPath().substring(5, resourceUrl.getPath().indexOf("!"));
        jarPath = java.net.URLDecoder.decode(jarPath, StandardCharsets.UTF_8);

        try (JarFile jar = new JarFile(jarPath)) {
            Enumeration<JarEntry> entries = jar.entries();

            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                String entryName = entry.getName();

                if (entryName.startsWith(resourcePath + "/") && entryName.endsWith(".map")) {
                    String fileName = entryName.substring(entryName.lastIndexOf('/') + 1);
                    Path targetFile = targetDir.resolve(fileName);

                    try (InputStream is = jar.getInputStream(entry);
                         OutputStream os = Files.newOutputStream(targetFile)) {
                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = is.read(buffer)) != -1) {
                            os.write(buffer, 0, bytesRead);
                        }
                    }
                }
            }
        }
    }

    /**
     * 从文件系统中复制资源
     */
    private void copyFileResources(Path sourceDir, Path targetDir) throws IOException {
        try (DirectoryStream<Path> stream = Files.newDirectoryStream(sourceDir, "*.map")) {
            for (Path sourceFile : stream) {
                Path targetFile = targetDir.resolve(sourceFile.getFileName());
                Files.copy(sourceFile, targetFile, StandardCopyOption.REPLACE_EXISTING);
            }
        }
    }

    /**
     * 加载地图文件夹中的地图名称
     */
    void loadMapNames(Path mapDir) {
        mapNames.clear();

        try (DirectoryStream<Path> stream = Files.newDirectoryStream(mapDir, "*.map")) {
            for (Path path : stream) {
                String fileName = path.getFileName().toString();
                mapNames.add(fileName);
            }
        } catch (IOException e) {
            throw new RuntimeException("无法加载地图名称: " + e.getMessage(), e);
        }

        // 确保至少有一个地图
        if (mapNames.isEmpty()) {
            throw new RuntimeException("地图文件夹中没有找到任何 .map 文件");
        }
    }

    @Override
    public void paint(Graphics g) {
        //双缓冲
        if (offScreenImage == null) {
            offScreenImage = this.createImage(this.getWidth(), this.getHeight());
        }
        Graphics gOff = offScreenImage.getGraphics();

        Image img = rm.imageMap.get("option");
        gOff.drawImage(img, 0, 0, null);

        gOff.setColor(Color.white);
        gOff.setFont(new Font("微软雅黑", Font.BOLD, 24));
        gOff.drawString(mapNames.get(level), 50, 440);
        //012对应普通，中等，困难
        switch (diff) {
            case 0:
                gOff.drawString("普通", 65, 230);
                break;
            case 1:
                gOff.drawString("中等", 65, 230);
                break;
            case 2:
                gOff.drawString("困难", 65, 230);
                break;
        }
        gOff.drawString("Esc返回", 45, 40);

        BufferedImage mapImage = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
        Graphics2D gMap = mapImage.createGraphics();
        gMap.setComposite(AlphaComposite.Clear);
        gMap.fillRect(0, 0, 800, 600);
        gMap.setComposite(AlphaComposite.SrcOver);

        gMap.setStroke(new BasicStroke(3)); // 设置边框粗细
        gMap.setColor(Color.WHITE);
        gMap.drawRect(0, 0, 800, 600);

        try {
            mapData = MapLoader.getMap("map/" + mapNames.get(level));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }



        for (String terrainType : mapData.keySet()) {
            List<Point> points = mapData.get(terrainType);
            int w = 20, h = 20;
            if (terrainType.equals("base") || terrainType.equals("elite") || terrainType.equals("BOSS") || terrainType.equals("player1") || terrainType.equals("player2")) w = h = 40;
            for (Point point : points) {
                gMap.drawImage(rm.imageMap.get(terrainType), point.x, point.y, w, h, null);
            }
        }



        g.drawImage(offScreenImage, 0, 0, null);
        g.drawImage(mapImage, 250, 100, 480, 360, null);
    }

    private class KeyboardListener extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            switch (e.getKeyCode()) {
                case KeyEvent.VK_W:
                    if (!mapNames.isEmpty()) {
                        level = (level + 1) % mapNames.size();
                        repaint();
                    }
                    break;

                case KeyEvent.VK_A:
                    diff = (diff + 3 - 1) % 3;
                    repaint();
                    break;

                case KeyEvent.VK_S:
                    if (!mapNames.isEmpty()) {
                        level = (level - 1 + mapNames.size()) % mapNames.size();
                        repaint();
                    }
                    break;

                case KeyEvent.VK_D:
                    diff = (diff + 1) % 3;
                    repaint();
                    break;

                case KeyEvent.VK_ENTER:
                    if (!mapNames.isEmpty() && level < mapNames.size()) {
                        mjf.startGame(playerNum, diff, mapNames.get(level));
                    }
                    break;

                case KeyEvent.VK_ESCAPE:
                    mjf.showIndex();
                    break;
            }
        }
    }
}